/*
Long Nguyen 
UID: 005-30-140
Assignment 1: Draw an U letter using only 
void drawPoint(...)
*/

#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#elif defined(_WIN32)
#include <windows.h>
#include "glut.h"
#else
#include <cstdlib>
#include <GL/glut.h>
#endif

#include <cstdio>

using namespace std;

int main_window = 1;
int position_x = 100;
int position_y = 100;
int width = 512;
int height = 512;

void idle(void)
{
	if (glutGetWindow() != main_window)
		glutSetWindow(main_window);

	// just keep redrawing the scene over and over
	glutPostRedisplay();
}


void keyboard(unsigned char key, int x, int y)
{
	switch(key)
	{
	// quit
	case 27: 
	case 'q':
	case 'Q':
		exit(0);
		break;
    }
    glutPostRedisplay();
}

// the window has changed shapes, fix ourselves up
void reshape(int x, int y)
{
	width = x;
	height = y;
	printf("%d %d\n", x,y);
	glViewport(0,0,width,height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,width,0,height,-100,10000);
	glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

void drawPoint(int x, int y, float r, float g, float b)
{
    //Set color
    glColor3f(r,g,b);
    
    //Set position
    glVertex3f(x,y,0);
}

void display( )
{
	glMatrixMode(GL_MODELVIEW);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    //Clear background to black 
	glClearColor(0,0,0,0);
	glLoadIdentity();
    

    glBegin(GL_POINTS);

	//
	// left head
	//
	int headW = 100;
	int headH = 80;
	int startx=136;
	int starty=416;

	// draw top head border
	for (int i=startx-1; i<=startx+headW+1; i++) {
		drawPoint(i, starty+1, 1, 1, 1);
	}

	for (int j=starty; j>=starty-headH; j--) {

		drawPoint(startx-1, j, 1, 1, 1);
		for (int i=startx; i<=startx+headW; i++) {
			drawPoint(i, j, 1, 0, 0);
		}
		drawPoint(startx+headW+1, j, 1, 1, 1);		
	}
	
	//
	// Right head
	//
	int startxR=512-startx;		
	
	for (int i=startxR+1; i>=startxR-headW-1; i--) {
		drawPoint(i, starty+1, 1, 1, 1);
	}

	for (int j=starty; j>=starty-headH; j--) {

		drawPoint(startxR+1, j, 1, 1, 1);
		for (int i=startxR; i>=startxR-headW; i--) {
			drawPoint(i, j, 1, 0, 0);
		}
		drawPoint(startxR-headW-1, j, 1, 1, 1);		
	}

	//
	// left body
	//
	int bodyH=160;
	int bodyW=50;
	int indent=25;

	startx += indent;
	starty -= headH;

	for (int i=startx-indent-1; i<startx; i++) {
		drawPoint(i, starty, 1, 1, 1);
	}
	for (int i=startx+bodyW+1; i<=startx+bodyW+indent+1; i++) {
		drawPoint(i, starty, 1, 1, 1);
	}

	for (int j=starty; j>=starty-bodyH; j--) {
	
		drawPoint(startx-1, j, 1, 1, 1);
		for (int i=startx; i<=startx+bodyW; i++) {
			drawPoint(i, j, 1, 0, 0);
		}
		drawPoint(startx+bodyW+1, j, 1, 1, 1);
	}

	//
	// Right body
	//
	startxR -= indent;	

	for (int i=1; i<=indent; i++) {
		drawPoint(startxR+indent+1-i, starty, 1, 1, 1);
	}
	for (int i=1; i<=indent; i++) {
		drawPoint(startxR-bodyW-i-1, starty, 1, 1, 1);
	}

	for (int j=starty; j>=starty-bodyH; j--) {
	
		drawPoint(startxR+1, j, 1, 1, 1);
		for (int i=startxR; i>=startxR-bodyW; i--) {
			drawPoint(i, j, 1, 0, 0);
		}
		drawPoint(startxR-bodyW-1, j, 1, 1, 1);
	}

	//
	// left base
	//
	starty -= bodyH;
	int add=50;
	int baseW=bodyW+add;
	int baseH=20;

	for (int i=1; i<=add; i++) {
		drawPoint(startx+bodyW+i, starty+1, 1, 1, 1);
	}
	
	for (int j=starty; j>=starty-baseH; j--) {
	
		drawPoint(startx-1, j, 1, 1, 1);
		for (int i=startx; i<=startx+baseW; i++) {
			drawPoint(i, j, 1, 0, 0);
		}		
	}

	//
	// right base
	//
	for (int i=1; i<=add; i++) {
		drawPoint(startxR-bodyW-i, starty+1, 1, 1, 1);
	}
	for (int j=starty; j>=starty-baseH; j--) {
	
		drawPoint(startxR+1, j, 1, 1, 1);
		for (int i=startxR; i>=startxR-baseW; i--) {
			drawPoint(i, j, 1, 0, 0);
		}		
	}
	
	//
	// left foot
	//
	starty -= baseH;
	int footW=baseW;
	int footH=60;
	int offset=0;

	for (int j=starty; j>=starty-footH; j--) {
	
		drawPoint(startx+offset-1, j, 1, 1, 1);
		for (int i=startx+offset; i<=startx+footW; i++) {
			drawPoint(i, j, 1, 0, 0);
		}		
		offset++;
	}
	offset--;
	// bottom border
	for (int i=0; i<=footW-offset; i++) {
		drawPoint(startx+offset+i, starty-footH-1, 1, 1, 1);
	}

	//
	// right foot
	//
	offset=0;
	for (int j=starty; j>=starty-footH; j--) {
	
		drawPoint(startxR-offset+1, j, 1, 1, 1);
		for (int i=startxR-offset; i>=startxR-footW; i--) {
			drawPoint(i, j, 1, 0, 0);
		}		
		offset++;
	}
	offset--;
	for (int i=0; i<=footW-offset; i++) {
		drawPoint(startxR-offset-i, starty-footH-1, 1, 1, 1);
	}
	

	//for (int i=128; i<384; i++)
 //   {
 //       for (int j=128; j<384; j++)
 //       {
 //           //draw a white squared
 //           drawPoint(i,j, 1,1,1);

 //       }
 //   }
	glEnd();
	glutSwapBuffers();
}

int main(int argc,	char* argv[])
{
	//
	// create the glut window
	//
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
	glutInitWindowSize(width, height);
	glutInitWindowPosition(100,100);
	main_window = glutCreateWindow("Assignment 1");
    glPointSize(1);

	glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);

	glMatrixMode(GL_PROJECTION);
    glOrtho(0,width,0,height,-100,10000);
	glMatrixMode(GL_MODELVIEW);
	// give control over to glut
	glutMainLoop();
	
	return 0;
}
